home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / lang / ClassLoader.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  42.2 KB  |  1,233 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)ClassLoader.java    1.123 98/09/28
  3.  *
  4.  * Copyright 1994-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang;
  16.  
  17. import java.io.InputStream;
  18. import java.io.IOException;
  19. import java.io.StringWriter;
  20. import java.io.PrintWriter;
  21. import java.io.File;
  22. import java.util.Hashtable;
  23. import java.util.Enumeration;
  24. import java.util.Vector;
  25. import java.util.Stack;
  26. import java.util.HashMap;
  27. import java.util.Map;
  28. import java.util.NoSuchElementException;
  29. import java.util.jar.Manifest;
  30. import java.net.URL;
  31. import java.net.MalformedURLException;
  32. import java.security.AccessController;
  33. import java.security.PrivilegedAction;
  34. import java.security.ProtectionDomain;
  35. import java.security.PermissionCollection;
  36. import java.security.CodeSource;
  37. import java.security.Policy;
  38. import sun.misc.URLClassPath;
  39. import sun.misc.Resource;
  40. import sun.misc.CompoundEnumeration;
  41. //import sun.misc.Launcher;
  42.  
  43. /**
  44.  * The class <code>ClassLoader</code> is an abstract class. 
  45.  * A class loader is an object that is responsible for loading 
  46.  * classes. Given the name of a class, it should attempt to locate 
  47.  * or generate data that constitutes a definition for the class. A 
  48.  * typical strategy is to transform the name into a file
  49.  * name and then read a "class file" of that name from a file system. 
  50.  * <p>
  51.  * Every <code>Class</code> object contains a 
  52.  * {@link Class#getClassLoader() reference} to the 
  53.  * <code>ClassLoader</code> that defined it.
  54.  * <p>
  55.  * Class objects for array classes are not created by class loaders, but 
  56.  * are created automatically as required by the Java runtime. The class 
  57.  * loader for an array class, as returned by {@link Class#getClassLoader()} 
  58.  * is the same as the class loader for its element type; if the element 
  59.  * type is a primitive type, then the array class has no class loader.
  60.  * <p>
  61.  * Applications implement subclasses of <code>ClassLoader</code> in 
  62.  * order to extend the manner in which the Java virtual machine 
  63.  * dynamically loads classes. 
  64.  * <p>
  65.  * Class loaders may typically be used by security managers to
  66.  * indicate security domains.
  67.  * <p>
  68.  * The <code>ClassLoader</code> class uses a delegation model to 
  69.  * search for classes and resources. Each instance of 
  70.  * <code>ClassLoader</code> has an associated parent class loader. 
  71.  * When called upon to find a class or resource, a 
  72.  * <code>ClassLoader</code> instance will delegate the search for 
  73.  * the class or resource to its parent class loader before 
  74.  * attempting to find the class or resource itself.  The virtual 
  75.  * machine's built-in class loader, called the bootstrap class loader, 
  76.  * does not itself have a parent but may serve as the parent of a 
  77.  * <code>ClassLoader</code> instance.
  78.  * <p>
  79.  * Normally, the Java virtual machine loads classes from the local 
  80.  * file system in a platform-dependent manner. For example, on UNIX 
  81.  * systems, the virtual machine loads classes from the directory 
  82.  * defined by the <code>CLASSPATH</code> environment variable. 
  83.  * <p>
  84.  * However, some classes may not originate from a file; they may 
  85.  * originate from other sources, such as the network, or they could 
  86.  * be constructed by an application. The method 
  87.  * <code>defineClass</code> converts an array of bytes into an 
  88.  * instance of class <code>Class</code>. Instances of this newly 
  89.  * defined class can be created using the <code>newInstance</code> 
  90.  * method in class <code>Class</code>. 
  91.  * <p>
  92.  * The methods and constructors of objects created by a class loader 
  93.  * may reference other classes. To determine the class(es) referred 
  94.  * to, the Java virtual machine calls the <code>loadClass</code> 
  95.  * method of the class loader that originally created the class. 
  96.  * <p>
  97.  * For example, an application could create a network class loader 
  98.  * to download class files from a server. Sample code might look like:
  99.  * <blockquote><pre>
  100.  *   ClassLoader loader = new NetworkClassLoader(host, port);
  101.  *   Object main = loader.loadClass("Main", true).newInstance();
  102.  *      . . .
  103.  * </pre></blockquote>
  104.  * <p>
  105.  * The network class loader subclass must define the methods 
  106.  * <code>findClass</code> and <code>loadClassData</code> 
  107.  * to load a class from the network. Once it 
  108.  * has downloaded the bytes that make up the class, it should use the 
  109.  * method <code>defineClass</code> to create a class instance. A 
  110.  * sample implementation is: 
  111.  * <p><hr><blockquote><pre>
  112.  *     class NetworkClassLoader extends ClassLoader {
  113.  *         String host;
  114.  *         int port;
  115.  *
  116.  *         public Class findClass(String name) {
  117.  *             byte[] b = loadClassData(name);
  118.  *             return defineClass(name, b, 0, b.length);
  119.  *         }
  120.  *
  121.  *         private byte[] loadClassData(String name) {
  122.  *             // load the class data from the connection
  123.  *              . . .
  124.  *         }
  125.  *     }
  126.  * </pre></blockquote><hr>
  127.  *
  128.  * @version 1.123, 09/28/98
  129.  * @see     java.lang.Class
  130.  * @see     java.lang.Class#newInstance()
  131.  * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
  132.  * @see     java.lang.ClassLoader#loadClass(java.lang.String, boolean)
  133.  * @see     java.lang.ClassLoader#resolveClass(java.lang.Class)
  134.  * @since   JDK1.0
  135.  */
  136. public abstract class ClassLoader {
  137.     /*
  138.      * If initialization succeed this is set to true and security checks will
  139.      * succeed. Otherwise the object is not initialized and the object is
  140.      * useless.
  141.      */
  142.     private boolean initialized = false;
  143.  
  144.     /*
  145.      * The parent class loader for delegation.
  146.      */
  147.     private ClassLoader parent;
  148.  
  149.     /*
  150.      * The classes loaded by this class loader. The only purpose of this
  151.      * table is to keep the classes from being GC'ed until the loader
  152.      * is GC'ed.
  153.      */
  154.     private Vector classes = new Vector();
  155.  
  156.     /* 
  157.      * Called by the VM to record every loaded class with this loader.
  158.      */
  159.     void addClass(Class c) {
  160.         classes.addElement(c);
  161.     }
  162.  
  163.     /*
  164.      * The packages defined in this class loader. Each package name is
  165.      * mapped to its corresponding Package object.
  166.      */
  167.     private HashMap packages = new HashMap();
  168.  
  169.     /**
  170.      * Creates a new class loader using the specified parent class loader
  171.      * for delegation.
  172.      * <p>
  173.      * If there is a security manager, its <code>checkCreateClassLoader</code>
  174.      * method is called. This may result in a security exception. 
  175.      *
  176.      * @throws  SecurityException
  177.      *    if a security manager exists and its <code>checkCreateClassLoader</code> 
  178.      *    method doesn't allow creation of a new class loader.
  179.      * 
  180.      * @see       java.lang.SecurityException
  181.      * @see       java.lang.SecurityManager#checkCreateClassLoader()
  182.      * @since     JDK1.2
  183.      */
  184.     protected ClassLoader(ClassLoader parent) {
  185.     SecurityManager security = System.getSecurityManager();
  186.     if (security != null) {
  187.         security.checkCreateClassLoader();
  188.     }
  189.     this.parent = parent;
  190.     initialized = true;
  191.     }
  192.  
  193.     /**
  194.      * Creates a new class loader using the <code>ClassLoader</code>
  195.      * returned by the method <code>getSystemClassLoader()</code> as the
  196.      * parent class loader.
  197.      * <p>
  198.      * This constructor is invoked for every newly created class loader. 
  199.      * Because the class <code>ClassLoader</code> is abstract, it is not 
  200.      * possible to create a new instance of the class <code>ClassLoader</code> 
  201.      * itself; however, every constructor for a subclass of 
  202.      * <code>ClassLoader</code> necessarily invokes this constructor, 
  203.      * explicitly or implicitly, directly or indirectly. 
  204.      * <p>
  205.      * If there is a security manager, its <code>checkCreateClassLoader</code>
  206.      * method is called. This may result in a security exception. 
  207.      *
  208.      * @throws  SecurityException
  209.      *    if a security manager exists and its <code>checkCreateClassLoader</code> 
  210.      *    method doesn't allow creation of a new class loader.
  211.      * 
  212.      * @see       java.lang.SecurityException
  213.      * @see       java.lang.SecurityManager#checkCreateClassLoader()
  214.      */
  215.     protected ClassLoader() {
  216.     SecurityManager security = System.getSecurityManager();
  217.     if (security != null) {
  218.         security.checkCreateClassLoader();
  219.     }
  220.     this.parent = getSystemClassLoader();
  221.     initialized = true;
  222.     }
  223.  
  224.     /**
  225.      * Loads the class with the specified name. This method searches for 
  226.      * classes in the same manner as the {@link #loadClass(String, boolean)} 
  227.      * method. It is called by the Java virtual machine to resolve class 
  228.      * references. Calling this method is equivalent to calling 
  229.      * <code>loadClass(name, false)</code>.
  230.      *
  231.      * @param     name the name of the class
  232.      * @return    the resulting <code>Class</code> object
  233.      * @exception ClassNotFoundException if the class was not found
  234.      */
  235.     public Class loadClass(String name) throws ClassNotFoundException
  236.     {
  237.     return loadClass(name, false);
  238.     }
  239.  
  240.     /**
  241.      * Loads the class with the specified name.  The default implementation of
  242.      * this method searches for classes in the following order:<p>
  243.      *
  244.      * <ol>
  245.      * <li> Call {@link #findLoadedClass(String)} to check if the class has
  246.      *      already been loaded. <p>
  247.      * <li> Call the <code>loadClass</code> method on the parent class
  248.      *      loader.  If the parent is <code>null</code> the class loader
  249.      *      built-in to the virtual machine is used, instead. <p>
  250.      * <li> Call the {@link #findClass(String)} method to find the class. <p>
  251.      * </ol>
  252.      *
  253.      * If the class was found using the above steps, and the
  254.      * <code>resolve</code> flag is true, this method will then call the
  255.      * {@link #resolveClass(Class)} method on the resulting class object.
  256.      * <p>
  257.      * From JDK1.2, subclasses of ClassLoader are encouraged to override
  258.      * {@link #findClass(String)}, rather than this method.<p>
  259.      *
  260.      * @param     name the name of the class
  261.      * @param     resolve if <code>true</code> then resolve the class
  262.      * @return      the resulting <code>Class</code> object
  263.      * @exception ClassNotFoundException if the class could not be found
  264.      */
  265.     protected synchronized Class loadClass(String name, boolean resolve)
  266.     throws ClassNotFoundException
  267.     {
  268.     // First, check if the class has already been loaded
  269.     Class c = findLoadedClass(name);
  270.     if (c == null) {
  271.         try {
  272.         if (parent != null) {
  273.             c = parent.loadClass(name, false);
  274.         } else {
  275.             c = findBootstrapClass(name);
  276.         }
  277.         } catch (ClassNotFoundException e) {
  278.             // If still not found, then call findClass in order
  279.             // to find the class.
  280.             c = findClass(name);
  281.         }
  282.     }
  283.     if (resolve) {
  284.         resolveClass(c);
  285.     }
  286.     return c;
  287.     }
  288.  
  289.     /**
  290.      * Finds the specified class. This method should be overridden
  291.      * by class loader implementations that follow the new delegation model
  292.      * for loading classes, and will be called by the <code>loadClass</code>
  293.      * method after checking the parent class loader for the requested class.
  294.      * The default implementation throws <code>ClassNotFoundException</code>.
  295.      *
  296.      * @param  name the name of the class
  297.      * @return the resulting <code>Class</code> object
  298.      * @exception ClassNotFoundException if the class could not be found
  299.      * @since  JDK1.2
  300.      */
  301.     protected Class findClass(String name) throws ClassNotFoundException {
  302.     throw new ClassNotFoundException(name);
  303.     }
  304.  
  305.     /** 
  306.      * Converts an array of bytes into an instance of class
  307.      * <code>Class</code>.  Before the Class can be used it must be
  308.      * resolved. This method is deprecated in favor of the version
  309.      * that takes the class name as its first argument, and is more
  310.      * secure.
  311.      *
  312.      * @param      b   the bytes that make up the class data. The bytes in 
  313.      *             positions <code>off</code> through <code>off+len-1</code> 
  314.      *             should have the format of a valid class file as defined 
  315.      *             by the 
  316.      *             <a href="http://java.sun.com/docs/books/vmspec/">Java 
  317.      *             Virtual Machine Specification</a>.
  318.      * @param      off the start offset of the class data
  319.      * @param      len the length of the class data
  320.      * @return     the <code>Class</code> object that was created from the
  321.      *             specified class data
  322.      * @exception  ClassFormatError if the data did not contain a valid class
  323.      * @see        ClassLoader#loadClass(java.lang.String, boolean)
  324.      * @see        ClassLoader#resolveClass(java.lang.Class)
  325.      * @deprecated Replaced by defineClass(java.lang.String, byte[], int, int) 
  326.      */
  327.     protected final Class defineClass(byte[] b, int off, int len)
  328.     throws ClassFormatError
  329.     { 
  330.     return defineClass(null, b, off, len);
  331.     }
  332.  
  333.     /**
  334.      * Converts an array of bytes into an instance of class <code>Class</code>.
  335.      * Before the Class can be used it must be resolved.
  336.      * <p>
  337.      * This method assigns a default <code>ProtectionDomain</code> to 
  338.      * the newly defined class. The <code>ProtectionDomain</code> 
  339.      * contains the set of permissions granted when
  340.      * a call to <code>Policy.getPolicy().getPermissions()</code> is made with
  341.      * a Codesource of <code>null,null</code>. The default domain is 
  342.      * created on the first invocation of <code>defineClass</code>, and
  343.      * re-used on subsequent calls.
  344.      * <p>
  345.      * To assign a specific <code>ProtectionDomain</code> to the class,
  346.      * use the <code>defineClass</code> method that takes a 
  347.      * <code>ProtectionDomain</code> as one of its arguments.
  348.      *
  349.      * @param       name the expected name of the class, or <code>null</code>
  350.      *                  if not known, using '.' and not '/' as the separator
  351.      *                  and without a trailing ".class" suffix.
  352.      * @param      b    the bytes that make up the class data. The bytes in 
  353.      *             positions <code>off</code> through <code>off+len-1</code> 
  354.      *             should have the format of a valid class file as defined 
  355.      *             by the 
  356.      *             <a href="http://java.sun.com/docs/books/vmspec/">Java 
  357.      *             Virtual Machine Specification</a>.
  358.      * @param      off  the start offset of the class data
  359.      * @param      len  the length of the class data
  360.      * @return     the <code>Class</code> object that was created from the
  361.      *             specified class data
  362.      * @exception  ClassFormatError if the data did not contain a valid class
  363.      * @exception  IndexOutOfBoundsException if either <code>off</code> or 
  364.      *             <code>len</code> is negative, or if 
  365.      *             <code>off+len</code> is greater than <code>b.length</code>.
  366.      * @see        ClassLoader#loadClass(java.lang.String, boolean)
  367.      * @see        ClassLoader#resolveClass(java.lang.Class)
  368.      * @see        java.security.ProtectionDomain
  369.      * @see        java.security.Policy
  370.      * @see        java.security.CodeSource
  371.      * @see        java.security.SecureClassLoader
  372.      * @since      JDK1.1
  373.      */
  374.     protected final Class defineClass(String name, byte[] b, int off, int len)
  375.     throws ClassFormatError
  376.     { 
  377.     check();
  378.     Class c = defineClass0(name, b, off, len);
  379.     c.setProtectionDomain0(getDefaultDomain());
  380.     return c;
  381.     }
  382.  
  383.     /**
  384.      * Converts an array of bytes into an instance of class Class,
  385.      * with an optional ProtectionDomain. Before the
  386.      * class can be used it must be resolved.
  387.      * @param name the name of the class
  388.      * @param b the class bytes
  389.      * @param off the start offset of the class bytes
  390.      * @param len the length of the class bytes
  391.      * @param protectionDomain the ProtectionDomain of the class
  392.      * @return the <code>Class</code> object created from the data,
  393.      *         and optional ProtectionDomain.
  394.      */
  395.     protected final Class defineClass(String name, byte[] b, int off, int len,
  396.                       ProtectionDomain protectionDomain)
  397.     throws ClassFormatError
  398.     {
  399.     check();
  400.     if (protectionDomain == null) {
  401.         return defineClass(name, b, off, len);
  402.     } else {
  403.         Class c = defineClass0(name, b, off, len);
  404.         c.setProtectionDomain0(protectionDomain);
  405.         if (protectionDomain.getCodeSource() != null) {
  406.         java.security.cert.Certificate certs[] = 
  407.             protectionDomain.getCodeSource().getCertificates();
  408.         if (certs != null)
  409.             setSigners(c, certs);
  410.         }
  411.         return c;
  412.     }
  413.     }
  414.  
  415.     /**
  416.      * Links the specified class. 
  417.      * This (misleadingly named) method may be used by a class loader to 
  418.      * link a class. If the class <code>c</code> has already been linked, 
  419.      * then this method simply returns. Otherwise, the class is linked 
  420.      * as described in the "Execution" chapter of the <i>Java Language 
  421.      * Specification</i>.
  422.      *
  423.      * @param c the class to link
  424.      * @exception NullPointerException if <code>c</code> is <code>null</code>.
  425.      * @see   java.lang.ClassLoader#defineClass(java.lang.String,byte[],int,int)
  426.      */
  427.     protected final void resolveClass(Class c) { 
  428.     check();
  429.     resolveClass0(c);
  430.     }
  431.  
  432.     /**
  433.      * Finds a class with the specified name, loading it if necessary.<p>
  434.      *
  435.      * Prior to JDK1.2, this method loads a class from the local file
  436.      * system in a platform-dependent manner, and returns a class object
  437.      * that has no associated class loader.<p>
  438.      *
  439.      * Since JDK1.2, this method loads the class through the system class
  440.      * loader(see {@link #getSystemClassLoader()}).  Class objects returned
  441.      * might have <code>ClassLoader</code>s associated with them.  Subclasses
  442.      * of <code>ClassLoader</code> need not usually call this method, because
  443.      * most class loaders need to override just {@link #findClass(String)}.<p>
  444.      *
  445.      * @see       #ClassLoader(ClassLoader)
  446.      * @see       #getParent()
  447.      * @param     name the name of the class that is to be found
  448.      * @return    a system class with the given name
  449.      * @exception ClassNotFoundException if the class could not be found
  450.      */
  451.     protected final Class findSystemClass(String name)
  452.     throws ClassNotFoundException
  453.     {
  454.     check();
  455.     ClassLoader system = getSystemClassLoader();
  456.     if (system == null) {
  457.         return findBootstrapClass(name);
  458.     }
  459.     return system.loadClass(name);
  460.     }
  461.  
  462.     /**
  463.      * Returns the parent class loader for delegation. Some implementations 
  464.      * may use <code>null</code> to represent the bootstrap class 
  465.      * loader. This method will return <code>null</code> in such 
  466.      * implementations if this class loader's parent is the bootstrap 
  467.      * class loader. 
  468.      * <p>
  469.      * If a security manager is present, and the caller's class loader is
  470.      * not null and is not an ancestor of this class loader, then
  471.      * this method calls the security manager's <code>checkPermission</code> 
  472.      * method with a <code>RuntimePermission("getClassLoader")</code> 
  473.      * permission to ensure it's ok to access the parent class loader.
  474.      * If not, a <code>SecurityException</code> will be thrown.
  475.      *
  476.      * @throws SecurityException
  477.      *    if a security manager exists and its 
  478.      *    <code>checkPermission</code> method doesn't allow
  479.      *    access to this class loader's parent class loader.
  480.      * 
  481.      * @see SecurityManager#checkPermission
  482.      * @see java.lang.RuntimePermission
  483.      * 
  484.      * @since JDK1.2
  485.      */
  486.     public final ClassLoader getParent() {
  487.     if (parent == null)
  488.         return null;
  489.     SecurityManager sm = System.getSecurityManager();
  490.     if (sm != null) {
  491.         ClassLoader ccl = getCallerClassLoader();
  492.         if (ccl != null && !isAncestor(ccl)) {
  493.         sm.checkPermission(getGetClassLoaderPerm());
  494.         }
  495.     }
  496.     return parent;
  497.     }
  498.  
  499.     /**
  500.      * Sets the signers of a class. This should be called after defining a
  501.      * class.
  502.      * @param c the <code>Class</code> object
  503.      * @param signers the signers for the class
  504.      * @since JDK1.1
  505.      */
  506.     protected final void setSigners(Class c, Object[] signers) {
  507.         check();
  508.     c.setSigners(signers);
  509.     }
  510.  
  511.     private native Class defineClass0(String name, byte[] b, int off, int len);
  512.     private native void resolveClass0(Class c);
  513.     private native Class findBootstrapClass(String name)
  514.     throws ClassNotFoundException;
  515.  
  516.     /*
  517.      * Check to make sure the class loader has been initialized.
  518.      */
  519.     private void check() { 
  520.     if (!initialized) {
  521.         throw new SecurityException("ClassLoader object not initialized");
  522.     }
  523.     }
  524.  
  525.     /**
  526.      * Finds the class with the given name if it had been previously loaded
  527.      * through this class loader.
  528.      *
  529.      * @param  name the class name
  530.      * @return the <code>Class</code> object, or <code>null</code> if
  531.      *         the class has not been loaded
  532.      * @since  JDK1.1
  533.      */
  534.     protected native final Class findLoadedClass(String name);
  535.  
  536.     /**
  537.      * Finds the resource with the given name. A resource is some data
  538.      * (images, audio, text, etc) that can be accessed by class code in a way
  539.      * that is independent of the location of the code.<p>
  540.      *
  541.      * The name of a resource is a "/"-separated path name that identifies
  542.      * the resource.<p>
  543.      *
  544.      * This method will first search the parent class loader for the resource;
  545.      * if the parent is <code>null</code> the path of the class loader
  546.      * built-in to the virtual machine is searched.  That failing, this method
  547.      * will call <code>findResource</code> to find the resource.<p>
  548.      *
  549.      * @param  name resource name
  550.      * @return a URL for reading the resource, or <code>null</code> if
  551.      *         the resource could not be found or the caller doesn't have
  552.      *         adequate privileges to get the resource.
  553.      * @since  JDK1.1
  554.      * @see #findResource(String)
  555.      */
  556.     public URL getResource(String name) {
  557.     URL url;
  558.     if (parent != null) {
  559.         url = parent.getResource(name);
  560.     } else {
  561.         url = getBootstrapResource(name);
  562.     }
  563.     if (url == null) {
  564.         url = findResource(name);
  565.     }
  566.     return url;
  567.     }
  568.  
  569.     /**
  570.      * Finds all the resources with the given name. A resource is some data
  571.      * (images, audio, text, etc) that can be accessed by class code in a way
  572.      * that is independent of the location of the code.<p>
  573.      *
  574.      * The name of a resource is a "/"-separated path name that identifies the
  575.      * resource.<p>
  576.      *
  577.      * The search order is described in the documentation for {@link
  578.      * #getResource(String)}.<p>
  579.      *
  580.      * @param  name resource name
  581.      * @return an enumeration of URL to the resource. If no resources could
  582.      *         be found, the enumeration will be empty. Resources that the 
  583.      *         doesn't have access to will not be in the enumeration.
  584.      * @since  JDK1.2
  585.      * @see    #getResource
  586.      * @see #findResources
  587.      */
  588.     public final Enumeration getResources(String name) throws IOException {
  589.     Enumeration[] tmp = new Enumeration[2];
  590.     if (parent != null) {
  591.         tmp[0] = parent.getResources(name);
  592.     } else {
  593.         tmp[0] = getBootstrapResources(name);
  594.     }
  595.     tmp[1] = findResources(name);
  596.     
  597.     return new CompoundEnumeration(tmp);
  598.     }
  599.  
  600.     /**
  601.      * Returns an Enumeration of URLs representing all the resources with
  602.      * the given name. Class loader implementations should override this
  603.      * method to specify where to load resources from.
  604.      *
  605.      * @param  name the resource name
  606.      * @return an Enumeration of URLs for the resources
  607.      * @since  JDK1.2
  608.      */
  609.     protected Enumeration findResources(String name) throws IOException {
  610.     return new CompoundEnumeration(new Enumeration[0]);
  611.     }
  612.  
  613.     /**
  614.      * Finds the resource with the given name. Class loader
  615.      * implementations should override this method to specify where to
  616.      * find resources.
  617.      *
  618.      * @param  name the resource name
  619.      * @return a URL for reading the resource, or <code>null</code>
  620.      *         if the resource could not be found
  621.      * @since  JDK1.2
  622.      */
  623.     protected URL findResource(String name) {
  624.     return null;
  625.     }
  626.  
  627.     /**
  628.      * Find a resource of the specified name from the search path used to load
  629.      * classes.<p>
  630.      *
  631.      * In JDK1.1, the search path used is that of the virtual machine's
  632.      * built-in class loader.<p>
  633.      *
  634.      * Since JDK1.2, this method locates the resource through the system class
  635.      * loader (see {@link #getSystemClassLoader()}).
  636.      *
  637.      * @param  name the resource name
  638.      * @return a URL for reading the resource, or <code>null</code> if
  639.      *         the resource could not be found
  640.      * @since JDK1.1
  641.      */
  642.     public static URL getSystemResource(String name) {
  643.     ClassLoader system = getSystemClassLoader();
  644.     if (system == null) {
  645.         return getBootstrapResource(name);
  646.     }
  647.     return system.getResource(name);
  648.     }
  649.  
  650.     /**
  651.      * Find resources from the VM's built-in classloader.
  652.      */
  653.     private static URL getBootstrapResource(String name) {
  654.     URLClassPath ucp = getBootstrapClassPath();
  655.     Resource res = ucp.getResource(name);
  656.     return res != null ? res.getURL() : null;
  657.     }
  658.  
  659.     /**
  660.      * Finds all resources of the specified name from the search path used to
  661.      * load classes. The resources thus found are returned as an
  662.      * <code>Enumeration</code> of <code>URL</code> objects. <p>
  663.      *
  664.      * The search order is described in the documentation for {@link
  665.      * #getSystemResource(String)}. <p>
  666.      *
  667.      * @param  name the resource name
  668.      * @return an enumeration of resource URLs
  669.      * @since JDK1.2
  670.      */
  671.     public static Enumeration getSystemResources(String name)
  672.     throws IOException
  673.     {
  674.     ClassLoader system = getSystemClassLoader();
  675.     if (system == null) {
  676.         return getBootstrapResources(name);
  677.     }
  678.     return system.getResources(name);
  679.     }
  680.  
  681.     /**
  682.      * Find resources from the VM's built-in classloader.
  683.      */
  684.     private static Enumeration getBootstrapResources(String name)
  685.     throws IOException
  686.     {
  687.     final Enumeration e = getBootstrapClassPath().getResources(name);
  688.     return new Enumeration () {
  689.         public Object nextElement() {
  690.         return ((Resource)e.nextElement()).getURL();
  691.         }
  692.         public boolean hasMoreElements() {
  693.         return e.hasMoreElements();
  694.         }
  695.     };
  696.     }
  697.  
  698.     /*
  699.      * Returns the URLClassPath that is used for finding system resources.
  700.      */
  701.     static URLClassPath getBootstrapClassPath() {
  702.     if (bootstrapClassPath == null) {
  703.         bootstrapClassPath = sun.misc.Launcher.getBootstrapClassPath();
  704.     }
  705.     return bootstrapClassPath;
  706.     }
  707.  
  708.     private static URLClassPath bootstrapClassPath;
  709.  
  710.     /**
  711.      * Returns an input stream for reading the specified resource.
  712.      *
  713.      * The search order is described in the documentation for {@link
  714.      * #getResource(String)}.<p>
  715.      * 
  716.      * @param  name the resource name
  717.      * @return an input stream for reading the resource, or <code>null</code>
  718.      *         if the resource could not be found
  719.      * @since  JDK1.1
  720.      */
  721.     public InputStream getResourceAsStream(String name) {
  722.     URL url = getResource(name);
  723.     try {
  724.         return url != null ? url.openStream() : null;
  725.     } catch (IOException e) {
  726.         return null;
  727.     }
  728.     }
  729.  
  730.     /**
  731.      * Open for reading, a resource of the specified name from the search path
  732.      * used to load classes.<p>
  733.      *
  734.      * The search order is described in the documentation for {@link
  735.      * #getSystemResource(String)}. <p>
  736.      *
  737.      * @param  name the resource name
  738.      * @return an input stream for reading the resource, or <code>null</code>
  739.      *            if the resource could not be found
  740.      * @since JDK1.1
  741.      */
  742.     public static InputStream getSystemResourceAsStream(String name) {
  743.     URL url = getSystemResource(name);
  744.     try {
  745.         return url != null ? url.openStream() : null;
  746.     } catch (IOException e) {
  747.         return null;
  748.     }
  749.     }
  750.  
  751.     /**
  752.      * Returns the system class loader for delegation. This is the default
  753.      * delegation parent for new <code>ClassLoader</code> instances, and
  754.      * is typically the class loader used to start the application.
  755.      * <p>
  756.      * If a security manager is present, and the caller's class loader is
  757.      * not null and the caller's class loader is not the same as or an ancestor of
  758.      * the system class loader, then
  759.      * this method calls the security manager's <code>checkPermission</code> 
  760.      * method with a <code>RuntimePermission("getClassLoader")</code> 
  761.      * permission to ensure it's ok to access the system class loader.
  762.      * If not, a <code>SecurityException</code> will be thrown.
  763.      *
  764.      * @return the system <code>ClassLoader</code> for delegation, or
  765.      *         <code>null</code> if none
  766.      * @throws SecurityException
  767.      *        if a security manager exists and its 
  768.      *        <code>checkPermission</code> method doesn't allow 
  769.      *        access to the system class loader.
  770.      * @see SecurityManager#checkPermission
  771.      * @see java.lang.RuntimePermission
  772.      * @since JDK1.2
  773.      */
  774.     public static ClassLoader getSystemClassLoader() {
  775.     if (!sclSet) {
  776.             // Workaround for 4154308 (JDK 1.2FCS build breaker)
  777.             // Launcher l = Launcher.getLauncher();
  778.             sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
  779.         if (l != null) {
  780.         scl = l.getClassLoader();
  781.         }
  782.         sclSet = true;
  783.     }
  784.     if (scl == null) {
  785.         return null;
  786.     }
  787.     SecurityManager sm = System.getSecurityManager();
  788.     if (sm != null) {
  789.         ClassLoader ccl = getCallerClassLoader();
  790.         if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
  791.         sm.checkPermission(getGetClassLoaderPerm());
  792.         }
  793.     }
  794.     return scl;
  795.     }
  796.  
  797.     // Returns true if the specified class loader can be found
  798.     // in this class loader's delegation chain.
  799.     boolean isAncestor(ClassLoader cl) {
  800.     ClassLoader acl = this;
  801.     do {
  802.         acl = acl.parent;
  803.         if (cl == acl) {
  804.         return true;
  805.         }
  806.     } while (acl != null);
  807.     return false;
  808.     }
  809.  
  810.     // Returns the caller's class loader, or null if none
  811.     static native ClassLoader getCallerClassLoader();
  812.  
  813.     // The class loader for the system
  814.     private static ClassLoader scl;
  815.  
  816.     // Set to true once the system class loader has been set
  817.     private static boolean sclSet;
  818.  
  819.     // Permission to access system or parent class loader
  820.     private static RuntimePermission getClassLoaderPerm = null;
  821.  
  822.     static RuntimePermission getGetClassLoaderPerm()
  823.     {
  824.     if (getClassLoaderPerm == null)
  825.         getClassLoaderPerm = new RuntimePermission("getClassLoader");
  826.     return getClassLoaderPerm;
  827.     }
  828.  
  829.     /**
  830.      * Defines a package by name in this ClassLoader. This allows class
  831.      * loaders to define the packages for their classes. Packages must be
  832.      * created before the class is defined, and package names must be
  833.      * unique within a class loader and cannot be redefined or changed
  834.      * once created.
  835.      *
  836.      * @param name        the package name
  837.      * @param specTitle   the specification title
  838.      * @param specVersion the specification version
  839.      * @param specVendor  the specification vendor
  840.      * @param implTitle   the implementation title
  841.      * @param implVersion the implementation version
  842.      * @param implVendor  the implementation vendor
  843.      * @param sealBase    If not null, then this package is sealed with
  844.      *                    respect to the given code source URL. Otherwise,
  845.      *              the package is not sealed.
  846.      * @exception IllegalArgumentException if package name duplicates an
  847.      *            existing package either in this class loader or one of
  848.      *            its ancestors
  849.      * @since JDK1.2
  850.      */
  851.     protected Package definePackage(String name, String specTitle,
  852.                     String specVersion, String specVendor,
  853.                     String implTitle, String implVersion,
  854.                     String implVendor, URL sealBase)
  855.     throws IllegalArgumentException
  856.     {
  857.     synchronized (packages) {
  858.         Package pkg = getPackage(name);
  859.         if (pkg != null) {
  860.         throw new IllegalArgumentException(name);
  861.         }
  862.         pkg = new Package(name, specTitle, specVersion, specVendor,
  863.                   implTitle, implVersion, implVendor,
  864.                   sealBase);
  865.         packages.put(name, pkg);
  866.         return pkg;
  867.     }
  868.     }
  869.  
  870.     /**
  871.      * Returns a Package that has been defined by this class loader or any
  872.      * of its ancestors.
  873.      *
  874.      * @param  name the package name
  875.      * @return the Package corresponding to the given name, or null if not
  876.      *         found
  877.      * @since  JDK1.2
  878.      */
  879.     protected Package getPackage(String name) {
  880.     synchronized (packages) {
  881.         Package pkg = (Package)packages.get(name);
  882.         if (pkg == null) {
  883.         if (parent != null) {
  884.             pkg = parent.getPackage(name);
  885.         } else {
  886.             pkg = Package.getSystemPackage(name);
  887.         }
  888.         if (pkg != null) {
  889.             packages.put(name, pkg);
  890.         }
  891.         }
  892.         return pkg;
  893.     }
  894.     }
  895.  
  896.     /**
  897.      * Returns all of the Packages defined by this class loader and its
  898.      * ancestors.
  899.      *
  900.      * @since JDK1.2
  901.      */
  902.     protected Package[] getPackages() {
  903.     Map map;
  904.     synchronized (packages) {
  905.         map = (Map)packages.clone();
  906.     }
  907.     Package[] pkgs;
  908.     if (parent != null) {
  909.         pkgs = parent.getPackages();
  910.     } else {
  911.         pkgs = Package.getSystemPackages();
  912.     }
  913.     if (pkgs != null) {
  914.         for (int i = 0; i < pkgs.length; i++) {
  915.         map.put(pkgs[i].getName(), pkgs[i]);
  916.         }
  917.     }
  918.     return (Package[])map.values().toArray(new Package[map.size()]);
  919.     }
  920.  
  921.     /**
  922.      * Returns the absolute path name of a native library. The VM
  923.      * invokes this method to locate the native libraries that belong
  924.      * to classes loaded with this class loader. If this method returns
  925.      * <code>null</code>, the VM searches the library along the path
  926.      * specified as the <code>java.library.path</code> property.
  927.      *
  928.      * @param      libname   the library name
  929.      * @return     the absolute path of the native library
  930.      * @see        java.lang.System#loadLibrary(java.lang.String)
  931.      * @see        java.lang.System#mapLibraryName(java.lang.String)
  932.      * @since      JDK1.2
  933.      */
  934.     protected String findLibrary(String libname) {
  935.         return null;
  936.     }
  937.  
  938.     /**
  939.      * The inner class NativeLibrary denotes a loaded native library 
  940.      * instance. Every classloader contains a vector of loaded native
  941.      * libraries in the private field <code>nativeLibraries</code>.
  942.      * The native libraries loaded into the system are entered into
  943.      * the <code>systemNativeLibraries</code> vector.
  944.      *
  945.      * Every native library reuqires a particular version of JNI. This
  946.      * is denoted by the private jniVersion field. This field is set
  947.      * by the VM when it loads the library, and used by the VM to pass
  948.      * the correct version of JNI to the native methods.
  949.      *
  950.      * @version 1.123, 09/28/98
  951.      * @see     java.lang.ClassLoader
  952.      * @since   JDK1.2
  953.      */ 
  954.     static class NativeLibrary {
  955.         /* opaque handle to native library, used in native code. */ 
  956.         long handle;
  957.         /* the version of JNI environment the native library requires. */
  958.         private int jniVersion;
  959.         /* the class from which the library is loaded, also indicates
  960.        the loader this native library belongs. */
  961.         private Class fromClass;
  962.         /* the canonicalized name of the native library. */
  963.         String name;
  964.  
  965.         native void load(String name);
  966.         native long find(String name);
  967.         native void unload();
  968.  
  969.         public NativeLibrary(Class fromClass, String name) {
  970.             this.name = name;
  971.         this.fromClass = fromClass;
  972.     }
  973.  
  974.         protected void finalize() {
  975.         synchronized (loadedLibraryNames) {
  976.             if (fromClass.getClassLoader() != null && handle != 0) {
  977.             /* remove the native library name */ 
  978.             int size = loadedLibraryNames.size();
  979.             for (int i = 0; i < size; i++) {
  980.                 if (name.equals(loadedLibraryNames.elementAt(i))) {
  981.                 loadedLibraryNames.removeElementAt(i);
  982.                 break;
  983.             }
  984.             }
  985.             /* unload the library. */
  986.             ClassLoader.nativeLibraryContext.push(this);
  987.             try {
  988.             unload();
  989.             } finally {
  990.                 ClassLoader.nativeLibraryContext.pop();
  991.             }
  992.         }   
  993.         }
  994.     }
  995.         /* Called in the VM to determine the context class in 
  996.        JNI_Load/JNI_Unload */
  997.         static Class getFromClass() {
  998.             return ((NativeLibrary)
  999.             (ClassLoader.nativeLibraryContext.peek())).fromClass;
  1000.     }
  1001.     }
  1002.  
  1003.     /* the "default" domain. Set as the default ProtectionDomain
  1004.      * on newly created classses.
  1005.      */
  1006.     private ProtectionDomain defaultDomain = null;
  1007.  
  1008.     /* the "default" permissions, shared by the default domains.
  1009.      */
  1010.     private static PermissionCollection defaultPermissions = null;
  1011.  
  1012.     /*
  1013.      * returns (and initializes) the default domain.
  1014.      */
  1015.  
  1016.     private ProtectionDomain getDefaultDomain() {
  1017.     if (defaultDomain == null) {
  1018.         synchronized(ClassLoader.class) {
  1019.         if (defaultPermissions == null) {
  1020.             defaultPermissions = (PermissionCollection)
  1021.             AccessController.doPrivileged(new PrivilegedAction() {
  1022.                 public Object run() {
  1023.                 CodeSource cs = new CodeSource(null, null);
  1024.                 return Policy.getPolicy().getPermissions(cs);
  1025.                 }
  1026.             });
  1027.         }
  1028.  
  1029.         if (defaultDomain == null) {
  1030.             CodeSource cs = new CodeSource(null, null);
  1031.             defaultDomain = new ProtectionDomain(cs,
  1032.                              defaultPermissions);
  1033.         }
  1034.         }
  1035.     }
  1036.     return defaultDomain;
  1037.     }
  1038.  
  1039.     /* All native library names we've loaded. */ 
  1040.     private static Vector loadedLibraryNames = new Vector();
  1041.     /* Native libraries belonging to system classes. */
  1042.     private static Vector systemNativeLibraries = new Vector();
  1043.     /* Native libraries associated with the class loader. */
  1044.     private Vector nativeLibraries = new Vector();
  1045.  
  1046.     /* native libraries being loaded/unloaded. */
  1047.     private static Stack nativeLibraryContext = new Stack();
  1048.  
  1049.     /* The paths searched for libraries */
  1050.     static private String usr_paths[];
  1051.     static private String sys_paths[];
  1052.  
  1053.     private static String[] initializePath(String propname) {
  1054.         String ldpath = System.getProperty(propname, "");
  1055.     String ps = File.pathSeparator;
  1056.     int ldlen = ldpath.length();
  1057.     int i, j, n;
  1058.     // Count the separators in the path
  1059.     i = ldpath.indexOf(ps);
  1060.     n = 0;
  1061.     while (i >= 0) {
  1062.         n++;
  1063.         i = ldpath.indexOf(ps, i+1);
  1064.     }
  1065.  
  1066.     // allocate the array of paths - n :'s = n + 1 path elements
  1067.     String[] paths = new String[n + 1];
  1068.  
  1069.     // Fill the array with paths from the ldpath
  1070.     n = i = 0;
  1071.     j = ldpath.indexOf(ps);
  1072.     while (j >= 0) {
  1073.         if (j - i > 0) {
  1074.             paths[n++] = ldpath.substring(i, j);
  1075.         } else if (j - i == 0) { 
  1076.             paths[n++] = ".";
  1077.         }
  1078.         i = j + 1;
  1079.         j = ldpath.indexOf(ps, i);
  1080.     }
  1081.     paths[n] = ldpath.substring(i, ldlen);
  1082.     return paths;
  1083.     }
  1084.  
  1085.  
  1086.     /* Called in the java.lang.Runtime class to implement load
  1087.      * and loadLibrary.
  1088.      */
  1089.     static void loadLibrary(Class fromClass, String name,
  1090.                 boolean isAbsolute) {
  1091.         ClassLoader loader = 
  1092.         (fromClass == null) ? null : fromClass.getClassLoader();
  1093.         if (sys_paths == null) {
  1094.         usr_paths = initializePath("java.library.path");
  1095.         sys_paths = initializePath("sun.boot.library.path");
  1096.         }
  1097.         if (isAbsolute) {
  1098.         if (loadLibrary0(fromClass, new File(name))) {
  1099.             return;
  1100.         }
  1101.         throw new UnsatisfiedLinkError("Can't load library: " + name);
  1102.     }
  1103.     if (loader != null) {
  1104.         String libfilename = loader.findLibrary(name);
  1105.         if (libfilename != null) {
  1106.             File libfile = new File(libfilename);
  1107.             if (!libfile.isAbsolute()) {
  1108.             throw new UnsatisfiedLinkError(
  1109.     "ClassLoader.findClass failed to return an absolute path: " + libfilename);
  1110.         }
  1111.         if (loadLibrary0(fromClass, libfile)) {
  1112.             return;
  1113.         }
  1114.         throw new UnsatisfiedLinkError ("Can't load " + libfilename);
  1115.         }
  1116.     }
  1117.     for (int i = 0 ; i < sys_paths.length ; i++) {
  1118.         File libfile = new File(sys_paths[i], System.mapLibraryName(name));
  1119.         if (loadLibrary0(fromClass, libfile)) {
  1120.             return;
  1121.         }
  1122.     }
  1123.     if (loader != null) {
  1124.         for (int i = 0 ; i < usr_paths.length ; i++) {
  1125.             File libfile = new File(usr_paths[i], 
  1126.                     System.mapLibraryName(name));
  1127.         if (loadLibrary0(fromClass, libfile)) {
  1128.             return;
  1129.         }
  1130.         }
  1131.     }
  1132.     // Oops, it failed
  1133.         throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
  1134.     }
  1135.  
  1136.     private static boolean loadLibrary0(Class fromClass, final File file) {
  1137.     Boolean exists = (Boolean)
  1138.         AccessController.doPrivileged(new PrivilegedAction() {
  1139.         public Object run() {
  1140.             return new Boolean(file.exists());
  1141.         }
  1142.         });
  1143.     if (!exists.booleanValue()) {
  1144.         return false;
  1145.     } 
  1146.         String name;
  1147.     try {
  1148.         name = file.getCanonicalPath();
  1149.     } catch (IOException e) {
  1150.         return false;
  1151.     }
  1152.         ClassLoader loader = 
  1153.         (fromClass == null) ? null : fromClass.getClassLoader();
  1154.         Vector libs =
  1155.         loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1156.     synchronized (libs) {
  1157.         int size = libs.size();
  1158.         for (int i = 0; i < size; i++) {
  1159.             NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1160.         if (name.equals(lib.name)) {
  1161.             return true;
  1162.         }
  1163.         }        
  1164.  
  1165.         synchronized (loadedLibraryNames) {
  1166.             if (loadedLibraryNames.contains(name)) {
  1167.             throw new UnsatisfiedLinkError 
  1168.                 ("Native Library " + 
  1169.              name + 
  1170.              " already loaded in another classloader");
  1171.         }
  1172.         /* If the library is being loaded (must be by
  1173.          * the same thread, because Runtime.load and 
  1174.          * Runtime.loadLibrary are synchronous). The
  1175.          * reason is can occur is that the JNI_OnLoad
  1176.          * function can cause another loadLibrary call.
  1177.          *
  1178.          * Thus we can use a static stack to hold the list
  1179.          * of libraries we are loading.
  1180.          *
  1181.          * If there is a pending load operation for the
  1182.          * library, we immediately return success; otherwise,
  1183.          * we raise UnsatisfiedLinkError.
  1184.          */
  1185.         int n = nativeLibraryContext.size();
  1186.         for (int i = 0; i < n; i++) {
  1187.             NativeLibrary lib = (NativeLibrary)
  1188.                 nativeLibraryContext.elementAt(i);
  1189.             if (name.equals(lib.name)) {
  1190.                 if (loader == lib.fromClass.getClassLoader()) {
  1191.                 return true;
  1192.             } else {
  1193.                 throw new UnsatisfiedLinkError 
  1194.                     ("Native Library " + 
  1195.                  name + 
  1196.                  " is being loaded in another classloader");
  1197.             }
  1198.             }
  1199.         }
  1200.         NativeLibrary lib = new NativeLibrary(fromClass, name);
  1201.         nativeLibraryContext.push(lib);
  1202.         try {
  1203.             lib.load(name);
  1204.         } finally {
  1205.             nativeLibraryContext.pop();
  1206.         }
  1207.         if (lib.handle != 0) {
  1208.             loadedLibraryNames.addElement(name);
  1209.             libs.addElement(lib);
  1210.             return true;
  1211.         }
  1212.         return false;
  1213.         }
  1214.     }
  1215.     }
  1216.  
  1217.     /* Called in the VM class linking code. */
  1218.     static long findNative(ClassLoader loader, String name) {
  1219.         Vector libs = 
  1220.         loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1221.     synchronized (libs) {
  1222.         int size = libs.size();
  1223.         for (int i = 0; i < size; i++) {
  1224.             NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1225.         long entry = lib.find(name);
  1226.         if (entry != 0)
  1227.             return entry;
  1228.         }
  1229.     }
  1230.     return 0;
  1231.     }
  1232. }
  1233.